Python GPIO开发

Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.


python-periphery简介

python-periphery 是一个用于在Linux系统上通过Python进行硬件外设(GPIO、SPI、I2C等)开发的库。

主要特点

  • 基于Linux内核接口:使用标准的Linux字符设备接口(如 /dev/gpiochip0

  • 跨平台兼容性:适用于各种Linux单板计算机(Raspberry Pi、BeagleBone、Radxa等)

  • 纯Python实现:不需要编译C扩展,易于安装和部署

  • 支持多种外设:GPIO、SPI、I2C、MMIO、Serial、PWM等

支持的外设类型

外设类型

说明

GPIO

通用输入输出

SPI

串行外设接口

I2C

I²C总线通信

MMIO

内存映射I/O

Serial

串口通信

PWM

脉宽调制

安装python-periphery

安装pip3

首先确保系统已安装pip3:

sudo apt update
sudo apt install python3-pip -y

安装python-periphery库

由于Python 3.13+的PEP 668保护机制,需要使用 –break-system-packages 参数:

pip3 install python-periphery --break-system-packages

验证安装:

python3 -c "from periphery import GPIO; print('Installation successful!')"

提示:对于嵌入式开发板,使用 –break-system-packages 参数是安全的。如果您更倾向于使用虚拟环境,可以参考 Python虚拟环境使用 文档。

GPIO读取

重要提示:Pin3和Pin5默认配置为I2C9接口(SDA和SCL),如果需要作为GPIO使用,请确保没有其他设备正在占用这些引脚。

硬件准备

  • 主板

  • 杜邦线

软件准备

测试代码

以下代码使用python-periphery库来读取Pin3 (GPIO36)引脚的高低电平。

创建文件 gpio_input.py

from periphery import GPIO
import time

def read_gpio_input():# Configure GPIO input (modify pin number according to actual hardware)# Pin3 corresponds to GPIO36 (pin 36 of /dev/gpiochip4)try:# Initialize GPIO in input mode
        gpio_in = GPIO("/dev/gpiochip4", 36, "in")print("Starting GPIO input reading (press Ctrl+C to exit)")while True:# Read pin value
            value = gpio_in.read()print(f"GPIO input value: {value} (True=High, False=Low)")
            time.sleep(1)  # Read once per secondexcept KeyboardInterrupt:print("\nProgram exited")except Exception as e:print(f"Error occurred: {e}")finally:# Ensure resources are releasedtry:
            gpio_in.close()except:passif __name__ == "__main__":
    read_gpio_input()

测试步骤

  1. 将Pin3 (GPIO36)引脚接GND或3.3V引脚

  2. 将代码保存为 gpio_input.py

  3. 使用以下命令运行测试代码:

python3 gpio_input.py

实验现象

终端会输出 FalseTrue 信息:

  • False 代表低电平(引脚接GND)

  • True 代表高电平(引脚接3.3V)

示例输出:

Starting GPIO input reading (press Ctrl+C to exit)
GPIO input value: False (True=High, False=Low)
GPIO input value: False (True=High, False=Low)
GPIO input value: True (True=High, False=Low)

GPIO输出

硬件准备

  • 主板

  • 杜邦线

软件准备

测试代码

以下代码使用python-periphery库来控制Pin3 (GPIO36)引脚输出高低电平,然后通过Pin5 (GPIO37)引脚读取Pin3引脚的高低电平。

创建文件 gpio_output.py

from periphery import GPIO
import time

def gpio_output_with_feedback():# GPIO Configuration (modify pin numbers based on your hardware)# Pin3/GPIO36 (output) → maps to pin 36 of /dev/gpiochip4# Pin5/GPIO37 (input)  → maps to pin 37 of /dev/gpiochip4
    OUTPUT_PIN_CHIP = "/dev/gpiochip4"
    OUTPUT_PIN_NUMBER = 36  # Pin3/GPIO36 (output pin, controlled by the script)
    INPUT_PIN_NUMBER = 37   # Pin5/GPIO37 (input pin, reads output state)# Initialize GPIO objects as None first (for safe release later)
    gpio_out = None
    gpio_in = Nonetry:# Initialize Pin3/GPIO36 as OUTPUT mode
        gpio_out = GPIO(OUTPUT_PIN_CHIP, OUTPUT_PIN_NUMBER, "out")# Initialize Pin5/GPIO37 as INPUT mode
        gpio_in = GPIO(OUTPUT_PIN_CHIP, INPUT_PIN_NUMBER, "in")# Print test initialization infoprint("=== GPIO Output-Input Feedback Test Started ===")print(f"Controlled Pin (GPIO36): {OUTPUT_PIN_CHIP} - Pin {OUTPUT_PIN_NUMBER} (OUTPUT)")print(f"Monitoring Pin (GPIO37): {OUTPUT_PIN_CHIP} - Pin {INPUT_PIN_NUMBER} (INPUT)")print("Test Behavior: GPIO36 toggles HIGH/LOW every 1s; GPIO37 verifies GPIO36's state")print("Press Ctrl+C to stop the test\n")# Main loop: Toggle GPIO36 and read GPIO37 feedbackwhile True:# 1. Set GPIO36 to HIGH level
            gpio_out.write(True)
            time.sleep(0.1)  # Short delay for signal stabilization (avoid read lag)
            gpio37_reading = gpio_in.read()print(f"GPIO36 Output: HIGH (True) | GPIO37 Reading: {gpio37_reading}")# Keep GPIO36 HIGH for 1 second
            time.sleep(1)# 2. Set GPIO36 to LOW level
            gpio_out.write(False)
            time.sleep(0.1)  # Short delay for signal stabilization
            gpio37_reading = gpio_in.read()print(f"GPIO36 Output: LOW (False) | GPIO37 Reading: {gpio37_reading}")# Keep GPIO36 LOW for 1 second
            time.sleep(1)# Handle user-initiated exit (Ctrl+C)except KeyboardInterrupt:print("\n\nTest stopped by user (Ctrl+C)")# Handle other unexpected errors (e.g., GPIO access failure)except Exception as e:print(f"\nError during test: {str(e)}")# Ensure GPIO resources are released even if an error occursfinally:print("\nReleasing GPIO resources...")# Safely close GPIO36 (set to LOW first to avoid residual high level)if gpio_out:try:
                gpio_out.write(False)
                gpio_out.close()print(f"Successfully closed GPIO36 (Pin {OUTPUT_PIN_NUMBER})")except Exception as close_err:print(f"Failed to close GPIO36 (Pin {OUTPUT_PIN_NUMBER}): {str(close_err)}")# Safely close GPIO37if gpio_in:try:
                gpio_in.close()print(f"Successfully closed GPIO37 (Pin {INPUT_PIN_NUMBER})")except Exception as close_err:print(f"Failed to close GPIO37 (Pin {INPUT_PIN_NUMBER}): {str(close_err)}")print("Resource release complete.")# Run the test when the script is executed directlyif __name__ == "__main__":
    gpio_output_with_feedback()

测试步骤

  1. 将Pin3 (GPIO36)引脚和Pin5 (GPIO37)引脚进行短接

  2. 将代码保存为 gpio_output.py

  3. 使用以下命令运行测试代码:

sudo python3 gpio_output.py

注意:GPIO输出可能需要root权限,因此使用 sudo 运行。

实验现象

终端会输出 FalseTrue 信息:

  • False 代表低电平

  • True 代表高电平

示例输出:

=== GPIO Output-Input Feedback Test Started ===
Controlled Pin (GPIO36): /dev/gpiochip4 - Pin 36 (OUTPUT)
Monitoring Pin (GPIO37): /dev/gpiochip4 - Pin 37 (INPUT)
Test Behavior: GPIO36 toggles HIGH/LOW every 1s; GPIO37 verifies GPIO36's state
Press Ctrl+C to stop the test

GPIO36 Output: HIGH (True) | GPIO37 Reading: True
GPIO36 Output: LOW (False) | GPIO37 Reading: False
GPIO36 Output: HIGH (True) | GPIO37 Reading: True
GPIO36 Output: LOW (False) | GPIO37 Reading: False

GPIO引脚映射说明

在python-periphery中,你需要为GPIO引脚指定两个参数:

  1. GPIO芯片设备:Quectel Pi H1主要使用 /dev/gpiochip4

  2. 引脚编号:物理引脚对应的GPIO编号

40Pin引脚映射示例

物理引脚标识

引脚名称

GPIO编号

GPIO芯片

引脚编号

默认功能

Pin3

NFC_I2C_SDA

GPIO36

/dev/gpiochip4

36

I2C09_SDA

Pin5

NFC_I2C_SCL

GPIO37

/dev/gpiochip4

37

I2C09_SCL

Pin7

CAM2_RST

GPIO77

/dev/gpiochip4

77

GPIO

Pin11

GPIO_16

GPIO16

/dev/gpiochip4

16

GPIO/SPI/UART/I2C

Pin13

GPIO_17

GPIO17

/dev/gpiochip4

17

GPIO/SPI/UART/I2C

查看可用GPIO

使用 gpioinfo 命令查看所有可用的GPIO芯片和引脚:

# 安装gpiod工具sudo apt install gpiod -y

# 查看所有GPIO信息
gpioinfo

# 查看特定芯片
gpioinfo /dev/gpiochip4

常见问题

权限问题

如果遇到权限错误,可以:

  1. 使用 sudo 运行脚本

  2. 将用户添加到 gpio 用户组:

sudo usermod -a -G gpio $USER
  1. 注销并重新登录使权限生效

引脚占用问题

如果遇到 [Errno 16] Device or resource busy[Errno 1] Operation not permitted 错误:

检查引脚状态:

# 查看所有GPIO引脚状态
gpioinfo | grep "consumer="# 查看特定芯片的引脚占用情况
gpioinfo /dev/gpiochip4 | grep -E "(line|consumer)"

常见原因:

  • 引脚被其他进程占用(如I2C、SPI等)

  • 引脚已被系统功能使用

  • 其他GPIO程序正在运行

解决方法:

  • 选择未被占用的引脚(gpioinfo中显示为 input 且无 consumer 的引脚)

  • 如果你需要使用被占用的引脚,需要禁用相应的功能

引脚编号错误

如果遇到 [Errno 22] Invalid argument 错误:

原因:

  • 引脚编号不存在或不可用

  • 使用了错误的GPIO芯片设备

解决方法:

  1. 使用 gpioinfo 查看实际可用的引脚编号

  2. 确认使用正确的GPIO芯片(Quectel Pi H1主要使用 /dev/gpiochip4

调试技巧

查看可用的GPIO芯片:

ls -l /dev/gpiochip*

查看GPIO芯片详细信息:

gpioinfo

测试特定引脚:

# 使用gpioget读取引脚值sudo gpioget /dev/gpiochip4 36# 使用gpioset设置引脚值sudo gpioset /dev/gpiochip4 36=1  # 设置为高电平sudo gpioset /dev/gpiochip4 36=0  # 设置为低电平

参考资源